package com.zonda.rxjavaexample.chapter_1;


import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.zonda.rxjavaexample.R;
import com.zonda.rxjavaexample.Utils;
import com.zonda.rxjavaexample.apps.AppInfo;
import com.zonda.rxjavaexample.apps.AppInfoRich;
import com.zonda.rxjavaexample.apps.ApplicationAdapter;
import com.zonda.rxjavaexample.apps.ApplicationsList;

import java.io.File;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import rx.Observable;
import rx.Observer;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

public class FirstFragment extends Fragment {

  private RecyclerView mRecyclerView;
  private SwipeRefreshLayout mSwipeRefreshLayout;

  private ApplicationAdapter mAdapter;
  private File mFilesDir;

  @Nullable
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    super.onCreateView(inflater, container, savedInstanceState);

    View view = inflater.inflate(R.layout.chapter_1_layout, container, false);
    mRecyclerView = (RecyclerView) view.findViewById(R.id.fragment_first_example_list);
    mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById
        (R.id.fragment_first_example_swipe_container);

    return view;
  }

  @Override
  public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {

    super.onViewCreated(view, savedInstanceState);

    mRecyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));
    mAdapter = new ApplicationAdapter(new ArrayList<AppInfo>(), R.layout.applications_list_item);
    mRecyclerView.setAdapter(mAdapter);
    mSwipeRefreshLayout.setProgressViewOffset(false, 0,
        (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24,
            getResources().getDisplayMetrics()));

    mSwipeRefreshLayout.setEnabled(false);
    mSwipeRefreshLayout.setRefreshing(true);
    mRecyclerView.setVisibility(View.GONE);

    getFileDir().subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<File>() {
          @Override
          public void call(File file) {
            mFilesDir = file;
            refreshTheList();
          }
        });
  }

  private Observable<File> getFileDir() {

    return Observable.create(new Observable.OnSubscribe<File>() {
      @Override
      public void call(Subscriber<? super File> subscriber) {
        subscriber.onNext(getContext().getFilesDir());
        subscriber.onCompleted();
      }
    });
  }

  private void refreshTheList() {
    getApps().toSortedList().subscribe(new Observer<List<AppInfo>>() {
      @Override
      public void onCompleted() {
        Toast.makeText(getActivity(), "Here is the list!", Toast.LENGTH_LONG).show();
      }

      @Override
      public void onError(Throwable e) {
        Toast.makeText(getActivity(), "Something went wrong!", Toast.LENGTH_SHORT).show();
        mSwipeRefreshLayout.setRefreshing(false);
      }

      @Override
      public void onNext(List<AppInfo> appInfos) {
        mRecyclerView.setVisibility(View.VISIBLE);
        mAdapter.addApplications(appInfos);
        mSwipeRefreshLayout.setRefreshing(false);
        storeList(appInfos);
      }
    });
  }

  private void storeList(final List<AppInfo> appInfos) {
    ApplicationsList.getInstance().setList(appInfos);

    Schedulers.io().createWorker().schedule(new Action0() {
      @Override
      public void call() {
        SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
        Type appInfoType = new TypeToken<List<AppInfo>>() {
        }.getType();
        sharedPref.edit().putString("APPS", new Gson().toJson(appInfos, appInfoType)).apply();
      }
    });
  }

  private Observable<AppInfo> getApps() {
    return Observable.create(new Observable.OnSubscribe<AppInfo>() {
      @Override
      public void call(Subscriber<? super AppInfo> subscriber) {
        List<AppInfoRich> apps = new ArrayList<>();

        final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);

        List<ResolveInfo> infos =
            getActivity().getPackageManager().queryIntentActivities(mainIntent, 0);
        for (ResolveInfo info : infos) {
          apps.add(new AppInfoRich(getActivity(), info));
        }

        for (final AppInfoRich appInfo : apps) {
          Bitmap icon = Utils.drawableToBitmap(appInfo.getIcon());
          final String name = appInfo.getName();
          final String iconPath = mFilesDir + "/" + name;
          Utils.storeBitmap(getContext(), icon, name);

          if (subscriber.isUnsubscribed()) {
            return;
          }
          subscriber.onNext(new AppInfo(name, iconPath, appInfo.getLastUpdateTime()));
        }
        if (!subscriber.isUnsubscribed()) {
          subscriber.onCompleted();
        }
      }
    });
  }
}






























